#include "DepthEffect.h"
#include "Game.h"
#include <assert.h>

void DepthEffect::Initialize()
{
	mDevice = CDirect3D::Instance()->GetDevice();
	mDeviceContext = CDirect3D::Instance()->GetDeviceContext();

	DWORD shaderFlags = D3D11_CREATE_DEVICE_DEBUG ;


	ID3D10Blob* errorMessage;
	ID3D10Blob* compileShader;
	HRESULT result = D3DX11CompileFromFile(L"Contents\\Shaders\\DepthEffect.fx", 0, 0, 0, "fx_5_0", shaderFlags, 0, 0, &compileShader, &errorMessage, 0);

//	char* compileErrors = (char*)(errorMessage->GetBufferPointer());

	//assert(!FAILED(result));

	D3DX11CreateEffectFromMemory(compileShader->GetBufferPointer(), compileShader->GetBufferSize(), 0, mDevice, &mEffect);

	mTechnique = mEffect->GetTechniqueByName("DepthEffect");
	mFxMatrixWorld = mEffect->GetVariableByName("gWorldMatrix")->AsMatrix();
	mFxMatrixView = mEffect->GetVariableByName("gViewMatrix")->AsMatrix();
	mFxMatrixProjection = mEffect->GetVariableByName("gProjectionMatrix")->AsMatrix();

	InitInputLayout();
}

void DepthEffect::InitInputLayout()
{
	HRESULT result;
	unsigned int numElements;
	D3D11_INPUT_ELEMENT_DESC polygonLayout[4];

	// Create the vertex input layout description.
	// This setup needs to match the VertexType stucture in the ModelClass and in the shader.
	polygonLayout[0].SemanticName = "POSITION";
	polygonLayout[0].SemanticIndex = 0;
	polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	polygonLayout[0].InputSlot = 0;
	polygonLayout[0].AlignedByteOffset = 0;
	polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[0].InstanceDataStepRate = 0;

	polygonLayout[1].SemanticName = "TEXCOORD";
	polygonLayout[1].SemanticIndex = 0;
	polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
	polygonLayout[1].InputSlot = 0;
	polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[1].InstanceDataStepRate = 0;

	polygonLayout[2].SemanticName = "TEXCOORD";
	polygonLayout[2].SemanticIndex = 1;
	polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	polygonLayout[2].InputSlot = 0;
	polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[2].InstanceDataStepRate = 0;

	polygonLayout[3].SemanticName = "FOG";
	polygonLayout[3].SemanticIndex = 0;
	polygonLayout[3].Format = DXGI_FORMAT_R32_FLOAT;
	polygonLayout[3].InputSlot = 0;
	polygonLayout[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	polygonLayout[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[3].InstanceDataStepRate = 0;

	numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

	// Create the vertex input layout.
	D3DX11_PASS_SHADER_DESC effectVsDesc;
	mTechnique->GetPassByIndex(0)->GetVertexShaderDesc(&effectVsDesc);
	D3DX11_EFFECT_SHADER_DESC  effectVsDesc2;
	effectVsDesc.pShaderVariable->GetShaderDesc(effectVsDesc.ShaderIndex, &effectVsDesc2);
	const void *vsCodePtr = effectVsDesc2.pBytecode;
	unsigned vsCodeLen = effectVsDesc2.BytecodeLength;

	result = mDevice->CreateInputLayout(polygonLayout, numElements, vsCodePtr, vsCodeLen, &mInputLayout);

	assert(!FAILED(result));
}

void DepthEffect::Uninit()
{

}

void DepthEffect::SetTransformsMatrices(const XMFLOAT4X4 &pWorldMatrix, const XMFLOAT4X4 &pViewMatrix, const XMFLOAT4X4 &pProjectionMatrix)
{
	mFxMatrixWorld->SetMatrix(reinterpret_cast<const float*>(&pWorldMatrix));
	mFxMatrixView->SetMatrix(reinterpret_cast<const float*>(&pViewMatrix));
	mFxMatrixProjection->SetMatrix(reinterpret_cast<const float*>(&pProjectionMatrix));
}

void DepthEffect::Render(int pIndexCount)
{
	mDeviceContext->IASetInputLayout(mInputLayout);	
	mTechnique->GetPassByIndex(0)->Apply(0, mDeviceContext);
	mDeviceContext->DrawIndexed(pIndexCount, 0, 0);
}
